
use std::ffi::{CStr, CString};
use std::os::raw::{c_char, c_int};
use std::sync::Mutex;
use once_cell::sync::Lazy;
use chrono::Local;
use std::fs::OpenOptions;
use std::io::Write;

static LOGGER: Lazy<Mutex<Option<std::fs::File>>> = Lazy::new(|| Mutex::new(None));
static SIGNAL_CACHE: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new(String::from("{}")));

#[no_mangle]
pub extern "stdcall" fn init(config_path: *const c_char) -> c_int {
    let config_str = unsafe {
        if config_path.is_null() {
            return -1;
        }
        match CStr::from_ptr(config_path).to_str() {
            Ok(s) => s,
            Err(_) => return -2,
        }
    };

    let log_path = format!("tdxsignal_{}.log", Local::now().format("%Y%m%d"));
    let file = match OpenOptions::new()
        .create(true)
        .append(true)
        .open(&log_path)
    {
        Ok(f) => f,
        Err(_) => return -3,
    };

    let mut logger = LOGGER.lock().unwrap();
    *logger = Some(file);

    log_message(&format!("DLL initialized with config: {}", config_str));
    0
}

#[no_mangle]
pub extern "stdcall" fn push_quote(json_quote: *const c_char) -> c_int {
    let quote_str = unsafe {
        if json_quote.is_null() {
            return -1;
        }
        match CStr::from_ptr(json_quote).to_str() {
            Ok(s) => s,
            Err(_) => return -2,
        }
    };

    log_message(&format!("Received quote: {}", quote_str));

    // 模拟信号计算逻辑
    let signal = format!(
        r#"{{"time":"{}","signal":"BUY","price":10.5,"volume":1000}}"#,
        Local::now().format("%Y-%m-%d %H:%M:%S")
    );

    let mut cache = SIGNAL_CACHE.lock().unwrap();
    *cache = signal;

    0
}

#[no_mangle]
pub extern "stdcall" fn get_signal(out_buf: *mut c_char, buf_len: c_int) -> c_int {
    if out_buf.is_null() || buf_len <= 0 {
        return -1;
    }

    let cache = SIGNAL_CACHE.lock().unwrap();
    let signal_bytes = cache.as_bytes();

    if signal_bytes.len() >= buf_len as usize {
        return -2; // 缓冲区不足
    }

    unsafe {
        std::ptr::copy_nonoverlapping(
            signal_bytes.as_ptr() as *const c_char,
            out_buf,
            signal_bytes.len(),
        );
        *out_buf.add(signal_bytes.len()) = 0; // 添加 null 终止符
    }

    0
}

fn log_message(msg: &str) {
    let mut logger = LOGGER.lock().unwrap();
    if let Some(ref mut file) = *logger {
        let _ = writeln!(file, "[{}] {}", Local::now().format("%Y-%m-%d %H:%M:%S"), msg);
    }
}
